/**
 * package: services
 * author: zhaiyujin
 * description:
 */
package services

import (
	linq "github.com/ahmetb/go-linq"
	"github.com/kataras/iris/v12"
	"huanteng/vendors/validator"
	"huanteng/web/global/application"
	"huanteng/web/models"
	"huanteng/web/repositories"
	"huanteng/web/response"
)

type MenuService struct {
	repo *repositories.MenuRepository
	ra	 *repositories.AdminRepository
}

//创建菜单
func (m *MenuService) Create(menu *models.Menu)(err error) {

	err=m.repo.Create(menu)
	if err!=nil{
		return
	}

	//添加操作 这里不异步 了 为了haokan
	 m.OperateCreate(menu)

	return nil


}

//增加常规操作
func (m *MenuService) OperateCreate(menu *models.Menu) {
	//如果是菜单类型2会自动生成增删该改查
	if menu.MenuType!=2{
		return
	}
	//增加
	add := models.Menu{Status: 1, ParentID: menu.ID, URL: "/"+menu.Code , Name: "新增", Sequence: 1, MenuType: 3, Code: menu.Code + "Add", Method: "post",OperateType:"add"}
	m.repo.Create(&add)
	//删除
	del := models.Menu{Status: 1, ParentID: menu.ID, URL: "/"+menu.Code, Name: "删除", Sequence: 2, MenuType: 3, Code: menu.Code + "Del", Method: "delete",OperateType:"del"}
	m.repo.Create(&del)
	//查看
	view := models.Menu{Status: 1, ParentID: menu.ID, URL: "/"+menu.Code +"/:id", Name: "查看", Sequence: 3, MenuType: 3, Code: menu.Code + "View", Method: "get",OperateType:"view"}
	m.repo.Create(&view)
	//更新
	update := models.Menu{Status: 1, ParentID: menu.ID, URL: "/"+menu.Code , Name: "更新", Sequence: 4, MenuType: 3, Code: menu.Code + "Update", Method: "put",OperateType:"update"}
	m.repo.Create(&update)
	//列表
	list := models.Menu{Status: 1, ParentID: menu.ID, URL: "/"+menu.Code , Name: "列表", Sequence: 5, MenuType: 3, Code: menu.Code + "List", Method: "get",OperateType:"list"}
	m.repo.Create(&list)



}

//获取菜单列表
func (m *MenuService) Index(ctx iris.Context) {
	menu:=[]models.Menu{}
	where:=models.Menu{}
	where.Name= ctx.URLParam("key")
	where.ParentID=uint(ctx.URLParamUint64("parent_id"))
	where.MenuType=uint8(ctx.URLParamUint64("type"))


	m.repo.MenuList(&menu,where)

}

//获取所有菜单
func (m *MenuService) GetAll() []models.Menu{

	return m.repo.AllMenus()

}

//菜单详情
func (m *MenuService) Detail(id uint)models.Menu {

	return m.repo.FindById(id)

}
//更新菜单
func (m *MenuService) Update(ctx iris.Context) error{
	var menu models.Menu
   err:=validator.ValidateInfo(ctx.ReadJSON(&menu))
	if err!=nil{
		return err
	}
	m.repo.Update(&menu)

   return nil

}
//删除数据
func (m *MenuService) Delete(ctx iris.Context)error {
	var ids []uint
	err:= ctx.ReadJSON(&ids)
	if err!=nil{
		return err
	}
	err=m.repo.Delete(ids)
	if err!=nil{
		return err
	}
	return nil
}


//获取用户 权限操作列表
func (m *MenuService) MenuButtonList(adminsid uint,menuCode string)([]string,error) {
	var btnList []string
	//用户是否超级管理员

	//非超级管理员获取操作按钮
	//	menu:=models.Menu{}
		err :=m.repo.GetMenuButton(adminsid,menuCode,&btnList)
	if err!=nil{
		return nil,err
	}
	return btnList,nil

}


func (m *MenuService)GetInfo() (ad response.AdminData,err error) {
	var admin models.Admin
	id:=application.Uid
	//查询用户
	admin=m.ra.FindById(id)
	admin.Pwd=""
	//查询管理员菜单
	err,menu:=m.GetMenusByAdminsid(id)
	if err!=nil{
	 return response.AdminData{},err
   }
   ad.Menu=menu
   ad.User=admin

	return ad,nil
}
//查询用户权限菜单
func (m *MenuService) GetMenusByAdminsid(adminsid uint) (err error,menu []response.Menu)  {

	var menusById []models.Menu
//	var ret []models.Menu
	err = m.repo.GetMenuByAdminId(adminsid, &menusById)
	if err != nil || len(menusById) == 0 {
		return
	}

	//切片检索,并且按照parent_id 升序
	linq.From(menusById).OrderBy(func(c interface{}) interface{} {
		return c.(models.Menu).ParentID
	}).ToSlice(&menusById)

	var menus []response.Menu
	//当前方法应该让top作为顶级0来使用 1作为模块显示
	if len(menusById) > 0 {
		var topmenuid uint=menusById[0].ParentID
		if topmenuid==0{
			topmenuid=menusById[0].ID
		}
		menus = m.setMenu(menusById, topmenuid)
	}

   return nil,menus
}
// 递归菜单
func (m *MenuService)setMenu(menus []models.Menu, parentID uint) (out []response.Menu) {
	var menuArr []models.Menu
	//将子节点按照指定字段顺序排序
	linq.From(menus).Where(func(c interface{}) bool {
		return c.(models.Menu).ParentID == parentID
	}).OrderBy(func(c interface{}) interface{} {
		return c.(models.Menu).Sequence
	}).ToSlice(&menuArr)
	if len(menuArr) == 0 {
		return
	}
	noCache := false
	for _, item := range menuArr {
		menu := response.Menu{
			Path:      item.URL,
			Component: item.Code,
			Name:      item.Code,
			Meta:      response.MenuMeta{Title: item.Name, Icon: item.Icon, NoCache: noCache},
			Children:  []response.Menu{}}
		//将操作类型的隐藏
		if item.MenuType == 3 {
			menu.Hidden = true
		}
		//查询是否有子级
		menuChildren := m.setMenu(menus, item.ID)
		if len(menuChildren) > 0 {
			menu.Children = menuChildren
		}
		if item.MenuType == 2 {
			// 添加子级首页，有这一级NoCache才有效
			menuIndex := response.Menu{
				Path:      "index",
				Component: item.Code,
				Name:      item.Code,
				Meta:      response.MenuMeta{Title: item.Name, Icon: item.Icon, NoCache: noCache},
				Children:  []response.Menu{}}
			menu.Children = append(menu.Children, menuIndex)
			menu.Name = menu.Name + "index"
			menu.Meta = response.MenuMeta{}
		}
		out = append(out, menu)
	}
	return
}


// 向上查找父级菜单
func (m *MenuService) setMenuUp(menuMapAll map[uint]models.Menu, menuid uint, menuMap map[uint]models.Menu) {
	//查找所有菜单切片中是否存在该🆔
	menuModel, exists := menuMapAll[menuid]
	if exists {
		mid := menuModel.ID

		_, exists = menuMap[mid]
		if !exists {
			//如果菜单中存在菜单
			menuMap[mid] = menuModel
			m.setMenuUp(menuMapAll, menuModel.ParentID, menuMap)
		}
	}
}

